"""
人物数据访问层
"""
from typing import List, Optional, Dict, Any
from datetime import datetime
from sqlalchemy.orm import Session
from sqlalchemy import and_, or_

from app.models.character import Character, RoleType, Gender
from app.repositories.base import BaseRepository
from app.core.exceptions import NotFoundException

class CharacterRepository(BaseRepository[Character]):
    """人物数据访问类"""
    
    def __init__(self, db: Session):
        super().__init__(db, Character)
    
    def get_by_name(self, name: str) -> Optional[Character]:
        """根据姓名获取人物"""
        return self.db.query(Character).filter(
            and_(
                Character.name == name,
                Character.is_deleted == False
            )
        ).first()
    
    def get_by_role_type(self, role_type: RoleType) -> List[Character]:
        """根据角色类型获取人物列表"""
        return self.db.query(Character).filter(
            and_(
                Character.role_type == role_type,
                Character.is_deleted == False
            )
        ).all()
    
    def get_by_department(self, department: str) -> List[Character]:
        """根据部门获取人物列表"""
        return self.db.query(Character).filter(
            and_(
                Character.department == department,
                Character.is_deleted == False
            )
        ).all()
    
    def search_characters(self, keyword: str) -> List[Character]:
        """搜索人物"""
        return self.db.query(Character).filter(
            and_(
                or_(
                    Character.name.contains(keyword),
                    Character.position.contains(keyword),
                    Character.department.contains(keyword),
                    Character.description.contains(keyword)
                ),
                Character.is_deleted == False
            )
        ).all()
    
    def get_protagonist(self) -> Optional[Character]:
        """获取主角"""
        return self.db.query(Character).filter(
            and_(
                Character.role_type == RoleType.PROTAGONIST,
                Character.is_deleted == False
            )
        ).first()
    
    def get_colleagues(self) -> List[Character]:
        """获取所有同事"""
        return self.db.query(Character).filter(
            and_(
                Character.role_type == RoleType.COLLEAGUE,
                Character.is_deleted == False
            )
        ).all()
    
    def get_superiors(self) -> List[Character]:
        """获取所有上级"""
        return self.db.query(Character).filter(
            and_(
                Character.role_type == RoleType.SUPERIOR,
                Character.is_deleted == False
            )
        ).all()
    
    def get_by_age_range(self, min_age: int, max_age: int) -> List[Character]:
        """根据年龄范围获取人物"""
        return self.db.query(Character).filter(
            and_(
                Character.age >= min_age,
                Character.age <= max_age,
                Character.is_deleted == False
            )
        ).all()
    
    def get_by_gender(self, gender: Gender) -> List[Character]:
        """根据性别获取人物"""
        return self.db.query(Character).filter(
            and_(
                Character.gender == gender,
                Character.is_deleted == False
            )
        ).all()
    
    def update_basic_info(self, id: int, basic_info: Dict[str, Any]) -> Optional[Character]:
        """更新基本信息"""
        character = self.get_by_id(id)
        if not character:
            return None
        
        if character.basic_info is None:
            character.basic_info = {}
        
        # 更新JSON字段
        character.basic_info.update(basic_info)
        character.updated_at = datetime.utcnow()
        character.version += 1
        
        self.db.commit()
        self.db.refresh(character)
        return character
    
    def add_personality_tag(self, id: int, tag: str) -> Optional[Character]:
        """添加性格标签"""
        character = self.get_by_id(id)
        if not character:
            return None
        
        if character.personality_tags is None:
            character.personality_tags = []
        
        if tag not in character.personality_tags:
            character.personality_tags.append(tag)
            character.updated_at = datetime.utcnow()
            character.version += 1
            self.db.commit()
            self.db.refresh(character)
        
        return character
    
    def remove_personality_tag(self, id: int, tag: str) -> Optional[Character]:
        """移除性格标签"""
        character = self.get_by_id(id)
        if not character or character.personality_tags is None:
            return None
        
        if tag in character.personality_tags:
            character.personality_tags.remove(tag)
            character.updated_at = datetime.utcnow()
            character.version += 1
            self.db.commit()
            self.db.refresh(character)
        
        return character